package com.lihang.rabbit1.common.page;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 分页响应对象
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "分页响应对象")
public class PageRes<T> implements Serializable {

    private static final long serialVersionUID = 1L;

    @Schema(description = "总记录数")
    private long total;

    @Schema(description = "总页数")
    private long pages;

    @Schema(description = "当前页")
    private long currentPage;

    @Schema(description = "每页记录数")
    private long pageSize;

    @Schema(description = "是否有上一页")
    private boolean hasPrevious;

    @Schema(description = "是否有下一页")
    private boolean hasNext;

    @Schema(description = "数据列表")
    private List<T> records;

    /**
     * 创建空的分页结果
     * 
     * @return 空分页结果
     * @param <T> 记录类型
     */
    public static <T> PageRes<T> empty() {
        return empty(1, 10);
    }

    /**
     * 创建空的分页结果，指定页码和每页条数
     * 
     * @param current 当前页
     * @param size    每页大小
     * @return 空分页结果
     * @param <T> 记录类型
     */
    public static <T> PageRes<T> empty(long current, long size) {
        PageRes<T> result = new PageRes<>();
        result.setTotal(0);
        result.setPages(0);
        result.setCurrentPage(current);
        result.setPageSize(size);
        result.setHasPrevious(false);
        result.setHasNext(false);
        result.setRecords(Collections.emptyList());
        return result;
    }

    /**
     * 从MyBatis-Plus的Page对象创建PageRes对象
     * 
     * @param <T>  记录类型
     * @param page MyBatis-Plus的Page对象
     * @return PageRes对象
     */
    public static <T> PageRes<T> fromMybatisPage(Page<T> page) {
        if (page == null) {
            return empty();
        }
        return fromIPage(page);
    }

    /**
     * 从任意IPage对象创建PageRes对象
     * 
     * @param <T>  记录类型
     * @param page IPage对象
     * @return PageRes对象
     */
    public static <T> PageRes<T> fromIPage(IPage<T> page) {
        if (page == null) {
            return empty();
        }

        PageRes<T> result = new PageRes<>();
        result.setTotal(page.getTotal());
        result.setPages(page.getPages());
        result.setCurrentPage(page.getCurrent());
        result.setPageSize(page.getSize());
        result.setHasPrevious(page.getCurrent() > 1);
        result.setHasNext(page.getCurrent() < page.getPages());
        result.setRecords(page.getRecords());

        return result;
    }

    /**
     * 从IPage对象创建PageRes对象，并通过转换器转换记录类型
     * 
     * @param <T>       源记录类型
     * @param <R>       目标记录类型
     * @param page      IPage对象
     * @param converter 记录转换器
     * @return PageRes对象
     */
    public static <T, R> PageRes<R> fromIPage(IPage<T> page, Function<T, R> converter) {
        if (page == null) {
            return empty();
        }

        PageRes<R> result = new PageRes<>();
        result.setTotal(page.getTotal());
        result.setPages(page.getPages());
        result.setCurrentPage(page.getCurrent());
        result.setPageSize(page.getSize());
        result.setHasPrevious(page.getCurrent() > 1);
        result.setHasNext(page.getCurrent() < page.getPages());

        if (page.getRecords() != null) {
            result.setRecords(page.getRecords().stream()
                    .map(converter)
                    .collect(Collectors.toList()));
        } else {
            result.setRecords(Collections.emptyList());
        }

        return result;
    }
}